package ar.com.e2solver.solver;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class Population {

	private Collection<Individual> individuals;
	
	public Population() {
		individuals = new ArrayList<Individual>();
	}
	
	public Population(Collection<Individual> individuals) {
		this.individuals = new ArrayList<Individual>();
		this.individuals.addAll(individuals);
	}

	public void addAll(Collection<Individual> individuals){
		this.individuals.addAll(individuals);
	}
	
	public void add(Individual individuals){
		this.individuals.add(individuals);
	}
	
	public void removeAll(){
		this.individuals = new ArrayList<Individual>();
	}
	
	public double getVS() {
		double res = 0;
		double populationES = getES();
		
		for (Iterator<Individual> iterator = individuals.iterator(); iterator.hasNext();) {
			Individual individual = iterator.next();
			res += Math.pow((double)individual.getFitnessValue() - populationES, 2);
		}
		
		res = res / (double)(individuals.size() - 1);
		return res;
	}
	
	public double getES() {
		double res = 0;
		for (Iterator<Individual> iterator = individuals.iterator(); iterator.hasNext();) {
			Individual individual = iterator.next();
			res += (double)individual.getFitnessValue();
		}
		
		return (res / (double)individuals.size());
	}
	
	public Individual getBestIndividual(){
		List<Individual> indList = new ArrayList<Individual>(this.individuals);
		Collections.sort(indList, new IndividualComparator());
		return indList.get(indList.size() - 1);
	}

	public Collection<Individual> getIndividuals() {
		return new ArrayList<Individual>(individuals);
	}

	public int getSize() {
		return individuals.size();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((individuals == null) ? 0 : individuals.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Population other = (Population) obj;
		if (individuals == null) {
			if (other.individuals != null)
				return false;
		} else if (!individuals.equals(other.individuals))
			return false;
		return true;
	}
}
